//go:build linux
// +build linux

package goroutinepool

import (
	"fmt"
	"runtime"
	"syscall"
	"unsafe"
)

const (
	_CPU_SETSIZE = 1024
)

// cpuSet 表示CPU集合
type cpuSet [_CPU_SETSIZE / 64]uint64

// set 设置指定的CPU位
func (c *cpuSet) set(cpu int) {
	c[cpu/64] |= 1 << (uint(cpu) % 64)
}

// setCPUAffinity 设置当前线程的CPU亲和性（仅Linux）
func setCPUAffinity(cpu int) error {
	if cpu < 0 || cpu >= runtime.NumCPU() {
		return fmt.Errorf("invalid CPU core: %d (available: 0-%d)", cpu, runtime.NumCPU()-1)
	}

	runtime.LockOSThread()

	var cpuSetData cpuSet
	cpuSetData.set(cpu)

	// 使用syscall.RawSyscall调用sched_setaffinity
	// syscall number: 203 for sched_setaffinity on amd64
	_, _, err := syscall.RawSyscall(
		syscall.SYS_SCHED_SETAFFINITY,
		0, // pid = 0 表示当前线程
		uintptr(len(cpuSetData)*8),
		uintptr(unsafe.Pointer(&cpuSetData)),
	)

	if err != 0 {
		runtime.UnlockOSThread()
		return fmt.Errorf("failed to set CPU affinity: %v", err)
	}

	return nil
}
